// Copyright 2021 Guoyoko. All Rights Reserved.


#include "Graph/CustomizeFlowGraph.h"
#include "Asset/CustomizeFlowAsset.h"
#include "Node/CustomizeFlowTaskNode.h"
#include "Graph/CustomizeFlowGraphNode.h"
#include "Graph/CustomizeFlowGraphNode_Root.h"


namespace CustomizeFlowGraphHelpers
{

	void CreateChildren(UCustomizeFlowAsset* SelfAssetObj, UCustomizeFlowFlowTaskNode* RootNode, const UCustomizeFlowGraphNode* RootEdNode, int32 RootIndex = 0)
	{
		if (RootEdNode == nullptr)
		{
			return;
		}
		for (int32 PinIdx = 0; PinIdx < RootEdNode->Pins.Num(); PinIdx++)
		{
			UEdGraphPin* Pin = RootEdNode->Pins[PinIdx];
			if (Pin->Direction != EGPD_Output)
			{
				continue;
			}
			for (int32 Index = 0; Index < Pin->LinkedTo.Num(); Index++)
			{
				UCustomizeFlowGraphNode* GraphNode = Cast<UCustomizeFlowGraphNode>(Pin->LinkedTo[Index]->GetOwningNode());
				if (GraphNode == nullptr)
				{
					continue;
				}
				UCustomizeFlowFlowTaskNode* TaskInstance = Cast<UCustomizeFlowFlowTaskNode>(GraphNode->NodeInstance);
				TaskInstance->AddParentNode(RootNode);
				RootNode->AddChildNode(TaskInstance);
				CreateChildren(SelfAssetObj, TaskInstance, GraphNode);
			}
		}
	}

} // namespace SelfGraphHelpers


void UCustomizeFlowGraph::UpdateAsset(int32 UpdateFlags)
{
	UCustomizeFlowAsset* CusFlowAssetObj = Cast<UCustomizeFlowAsset>(GetOuter());
	if (CusFlowAssetObj == nullptr)	{ return; }

	UCustomizeFlowGraphNode_Root* RootNode = nullptr;
	for (int32 i = 0; i < Nodes.Num(); i++)
	{
		UCustomizeFlowGraphNode* Node = Cast<UCustomizeFlowGraphNode>(Nodes[i]);
		if (Node)
		{
			UCustomizeFlowFlowTaskNode* NodeInstance = Cast<UCustomizeFlowFlowTaskNode>(Node->NodeInstance);
			if (NodeInstance)
			{
				// mark all nodes as disconnected first, path from root will replace it with valid values later
				NodeInstance->Reset();
			}
		}
		if (RootNode == nullptr)
		{
			RootNode = Cast<UCustomizeFlowGraphNode_Root>(Nodes[i]);
		}
	}

	if (RootNode)
	{
		UCustomizeFlowGraphNode* RootTaskNode = Cast<UCustomizeFlowGraphNode>(RootNode->GetOutputNode());
		if (RootTaskNode)
		{
			CreateFSFromGraph(RootTaskNode);
		}
	}
}

void UCustomizeFlowGraph::CreateFSFromGraph(class UCustomizeFlowGraphNode* RootEdNode)
{
	UCustomizeFlowAsset* CusFlowAssetObj = Cast<UCustomizeFlowAsset>(GetOuter());
	CusFlowAssetObj->SetRootNode(RootEdNode->NodeInstance);
	UCustomizeFlowFlowTaskNode* RootTask = Cast<UCustomizeFlowFlowTaskNode>(RootEdNode->NodeInstance);
	RootTask->Reset();
	CustomizeFlowGraphHelpers::CreateChildren(CusFlowAssetObj, RootTask, RootEdNode);
}

